
/**
 * promise的实现
 */
function Promise(excutor) {
  const self = this
  self.status = 'pending'
  self.data = undefined
  self.callbacks = []
  function resolve(value) {
    if (self.status === 'pending') {
      self.status = 'resolved'
      self.data = value
      if (self.callbacks.length > 0) {
        setTimeout(() => {
          self.callbacks.forEach(obj => {
            obj.onResolved(value)
          })
        })
      }
    }
  }
  function reject(reason) {
    if (self.status === 'pending') {
      self.status = 'rejected'
      self.data = reason
      setTimeout(() => {
        self.callbacks.forEach(obj => {
          obj.onRejected(reason)
        })
      })

    }
  }
  try {
    excutor(resolve, reject)
  } catch {
    reject(self.data)
  }
}
Promise.prototype.then = function (onResolved, onRejected) {
  const self = this
  onResolved = typeof onResolved === 'function' ? onResolved : value => value
  onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
  return new Promise((resolve, reject) => {
    function hander(callback) {
      try {
        const result = callback(self.data)
        if (result instanceof Promise) {
          result.then(resolve, reject)
        } else {
          resolve(result)
        }
      } catch (error) {
        reject(error)
      }
    }
    if (self.status === 'resolved') {
      setTimeout(hander(onResolved), 0);
    } else if (self.status === 'rejected') {
      setTimeout(hander(onRejected), 0);
    } else {
      self.callbacks.push({
        onResolved(value) {
          hander(onResolved)
        },
        onRejected(value) {
          hander(onRejected)
        }
      })
    }
  })
}
Promise.prototype.catch = function (onRejected) {
  return this.then(null, onRejected)
}
Promise.resolve = function (value) {
  return new Promise((resolve, reject) => {
    if (value instanceof Promise) {
      value.then(resolve, reject)
    } else {
      resolve(value)
    }
  })
}
Promise.reject = function (reason) {
  return new Promise((resolve, reject) => {
    if (reason instanceof Promise) {
      reason.then(resolve, reject)
    } else {
      reject(reason)
    }
  })
}
Promise.all = function (promiseList) {
  return new Promise((resolve, reject) => {
    // 成功的次数，最后和length比较一下就知道是不是都成功了
    let count = 0
    const length = promiseList.length
    // 成功的结果
    const result = new Array(length)
    for (let i = 0; i < length; ++i) {
      Promise.resolve(promiseList[i]).then(
        value => {
          result[i] = value
          ++count
          if (count === length) {
            resolve(result)
          }
        },
        reason => {
          reject(reason)
        }
      )
    }
  })
}
Promise.race = function (promiseList) {
  return new Promise((resolve, reject) => {
    let length = promiseList.length
    for (let i = 0; i < length; ++i) {
      Promise.resolve(promiseList[i]).then(
        value=>{
          resolve(value)
        },
        reason=>{
          reject(reason)
        }
      )
    }
  })
}

// new Promise((resolve, reject) => {
//   setTimeout(() => {
//     if (Date.now() % 2 === 0) {
//       resolve(1)
//     } else {
//       reject(2)
//     }
//   }, 100);
// }).then(
//   value => {
//     console.log(value);
//   },
//   reason => {
//     console.log(reason);
//   }
// )

Promise.resolve(5).then(
  value => {
    console.log(value);
  },
)